﻿using System;
using System.Collections.Generic;
using System.Linq;
using Ue.CQRS.Bus;
using Ue.CQRS.Configuration;
using Ue.CQRS.DistributionManager;
using Ue.CQRS.Repositories;

namespace Ue.CQRS.Events
{
    /// <summary>
    /// 事件源相关信息构建工厂类
    /// 此对象必须是单例
    /// </summary>
    public class EventSourceFactory
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender">source使用动态参数，这样子，我们在调用下边BuildEventSource时TSource类型会自动生成相应的类型</param>
        /// <returns></returns>
        public static IEventSource Build(dynamic sender)
        {
            var sourceType = (Type)sender.GetType();
            var attribute =  sourceType.GetCustomAttributes(typeof(EventSourceAttribute), true).FirstOrDefault() as EventSourceAttribute;

            if (attribute == null)
            {
                throw new DomainException(string.Format("source不是有效的EventSource，请检查是否标识有EventSourceAttribute。对象：{0}", sourceType.FullName));
            }

            var name = string.IsNullOrWhiteSpace(attribute.Name) ? sourceType.Name : attribute.Name;


            return EventSourceFactory.BuildEventSource(sender, name);
        }

        private static EventSource<TSender> BuildEventSource<TSender>(TSender sender, string name)
        {
            var context = AppContext.GetContext();

            return new EventSource<TSender>(context.Resolve<IConfiguration>(),
                AppContext.GetContext().Resolve<IBus>(),
                context.Resolve<IEventRepository>(),
                name,
                sender);
        }
    }
}
